package com.roc.web.action.profitShare;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;

import java.util.List;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.roc.page.BaseSearchCondition;
import com.roc.page.PaginationBaseAction;
import com.roc.pojo.AuditingItem;
import com.roc.pojo.Operators;
import com.roc.pojo.OrgBean;
import com.roc.pojo.ProfitShare;
import com.roc.service.IAgentService;
import com.roc.service.IExcelService;
import com.roc.service.IMerchantServices;
import com.roc.service.IPagenitionService;
import com.roc.service.IProfitShareService;
import com.roc.service.IorgService;
import com.roc.service.ServiceException;
import com.roc.service.agent.IAgentInfoService;
import com.roc.service.operator.IPowerInfoService;
import com.roc.util.Constance;
import com.roc.util.ExcelUtil;
import com.roc.util.constant.Constant;
import com.roc.util.constant.OperatorsStatus;
import com.roc.util.constant.Role;
import com.roc.util.constant.SexStatus;

@Component
@Scope("prototype")
@Namespace("/profitShare")
public class ProfitShareQueryAction extends PaginationBaseAction {

	private Logger logger = LogManager.getLogger(ProfitShareQueryAction.class);

	private ProfitShareQuerySearchCondition searchCondition;

	private Operators merchant;

	private AuditingItem auditing;

	private List<OrgBean> orgList = new ArrayList<OrgBean>();

	private List<Operators> operatorsList = new ArrayList<Operators>();

	private String code;

	private InputStream excelFile;

	private String excelName;

	private Operators agent;

	@Autowired
	IorgService orgService;

	@Autowired
	IPagenitionService pagenitionService;

	@Autowired
	IMerchantServices merchantServices;

	@Autowired
	IPowerInfoService powerInfoService;

	@Autowired
	IAgentInfoService agentInfoService;
	@Autowired
	IMerchantServices merinfoService;
	@Autowired
	IAgentService agentService;

	@Autowired
	IProfitShareService profitShareService;

	@Autowired
	IExcelService excelService;

	@Action(value = "profitShareJsp", results = { @Result(name = "success", location = "/pages/profit_share/profit_share_query.jsp") })
	public String queryProfitShareJspAction() throws Exception {

		org();

		return SUCCESS;
	}

	@Action(value = "queryProfitShare", results = { @Result(name = "success", location = "/pages/profit_share/profit_share_query.jsp") })
	// 查询代理商
	public String queryProfitShareAction() throws Exception {

		if (searchCondition == null) {
			searchCondition = (ProfitShareQuerySearchCondition) getSearchConditionFromSession();
			if (searchCondition == null) {
				searchCondition = new ProfitShareQuerySearchCondition();
			}
		}
		try {

			org();

			String sql = getSql(searchCondition.getAccountNo(), searchCondition.getMinDate(), searchCondition.getMaxDate(), searchCondition.getOrgCode(),false);

			List<ProfitShare> list = profitShareService.queryProfitShare(sql);

			getRequest().setAttribute(SEARCH_RS_LIST, list);

			setSearchToConditionSession(searchCondition);

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
			addActionError(e.getMessage());
			return ERROR;
		}

		return SUCCESS;
	}

	// 查询机构
	public void org() throws Exception {
		Operators logingOperators = (Operators) getSession().getAttribute(
				Constant.SESSION_LOGIN_MERCHANT);
		orgList = orgService.listOrgs(logingOperators);
		getRequest().setAttribute("orgList", orgList);

		// 加载角色类型
		Map roleMap = new HashMap();
		if (logingOperators.getRoleType().equals(Role.AGENT.getCode())) {
			roleMap.put(Role.AGENT.getCode(), Role.AGENT.getName());
		} else {
			roleMap.put(Role.O_MANAGER.getCode(), Role.O_MANAGER.getName());
			roleMap.put(Role.AGENT.getCode(), Role.AGENT.getName());
		}
		getRequest().setAttribute("roleMap", roleMap);

	}

	protected void agentTheListSpecially(List<Object> list) {
		List<Object> tempList = new ArrayList<Object>();
		for (Object obj : list) {
			Operators temp = (Operators) obj;
			for (OrgBean bean : orgList) {
				if (temp.getOrgCode().equals(bean.getOrg_code())) {
					temp.setOrgName(bean.getOrg_name());
				}
			}

			for (Operators opera : operatorsList) {
				if (opera.getId() == temp.getSuperiorId()) {
					temp.setSuperiorName(opera.getRealName());
				}
			}
			temp.setSex(SexStatus.valueOfCode(temp.getSex()).getName());
			temp.setRoleName(Role.valueOfCode(temp.getRoleType()).getName());
			temp.setStatus(OperatorsStatus.valueOfCode(temp.getStatus())
					.getName());
			tempList.add(temp);
		}
		searchRsList = tempList;

	}

	// 导出excel
	@Action(value = "excelProFitShare", results = {
			@Result(name = "success", type = "stream", params = {
					"contentType", "application/vnd.ms-excel", "inputName",
					"excelFile", "contentDisposition",
					"attachment;filename=${excelName}.xlsx", "bufferSize",
					"1024*3" }),
			@Result(name = "error", location = "/error.jsp") })
	public String excelProFitShare() throws Exception {

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		try {

			org();

			String sql = getSql(searchCondition.getAccountNo(), searchCondition.getMinDate(), searchCondition.getMaxDate(), searchCondition.getOrgCode(),false);

			List<ProfitShare> list = profitShareService.queryProfitShare(sql);

			Operators agentOp = merchantServices
					.findMerchantByNo(searchCondition.getAccountNo());

			excelName = agentOp.getAccountNo() + "_"
					+ searchCondition.getMinDate().substring(0, 4)+"-"
					+ searchCondition.getMinDate().substring(4, 6);

			SXSSFWorkbook work = ExcelUtil.excelExport(agentOp, list,
					searchCondition.getMinDate());
			work.write(output);

			byte[] ba = output.toByteArray();
			excelFile = new ByteArrayInputStream(ba);
			output.flush();
			output.close();

		} catch (Exception e) {
			logger.info("######导出分润明细失败######");
			addActionError(e.getMessage());
			return ERROR;
		} finally {
			closeOutPut(output);
		}

		return SUCCESS;
	}

	private void closeOutPut(ByteArrayOutputStream output)
			throws ServiceException {

		try {
			if (output != null) {
				output.flush();
				output.close();
			}
		} catch (IOException e) {
			logger.error("########导出Excel关闭流失败######", e);
			throw new ServiceException("导出Excel关闭流失败！");
		}
	}

	@Override
	protected String getInitPageSize() {
		// TODO Auto-generated method stub
		return Constance.PAGE_MAX_SIZE + "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.roc.page.PaginationBaseAction#getSearchConditionFromSession()
	 */
	@Override
	protected BaseSearchCondition getSearchConditionFromSession() {
		// TODO Auto-generated method stub
		return (ProfitShareQuerySearchCondition) getSession().getAttribute(
				SEARCH_SESSION_PROFIT_SHARE_QUERY);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.roc.page.PaginationBaseAction#getSearchConditionFromSubClass()
	 */
	@Override
	protected BaseSearchCondition getSearchConditionFromSubClass()
			throws Exception {
		// TODO Auto-generated method stub
		return searchCondition;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.roc.page.PaginationBaseAction#setSearchConditionToSubClass(com.roc
	 * .page.BaseSearchCondition)
	 */
	@Override
	protected void setSearchConditionToSubClass(
			BaseSearchCondition searchCondition) throws Exception {
		this.setSearchConditionToSubClass(searchCondition);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.roc.page.PaginationBaseAction#setSearchToConditionSession(com.roc
	 * .page.BaseSearchCondition)
	 */
	@Override
	protected void setSearchToConditionSession(
			BaseSearchCondition searchCondition) {
		getSession().setAttribute(SEARCH_SESSION_PROFIT_SHARE_QUERY,
				searchCondition);
	}

	public Operators getMerchant() {
		return merchant;
	}

	public void setMerchant(Operators merchant) {
		this.merchant = merchant;
	}

	public ProfitShareQuerySearchCondition getSearchCondition() {
		return searchCondition;
	}

	public void setSearchCondition(
			ProfitShareQuerySearchCondition searchCondition) {
		this.searchCondition = searchCondition;
	}

	public AuditingItem getAuditing() {
		return auditing;
	}

	public void setAuditing(AuditingItem auditing) {
		this.auditing = auditing;
	}

	public List<OrgBean> getOrgList() {
		return orgList;
	}

	public void setOrgList(List<OrgBean> orgList) {
		this.orgList = orgList;
	}

	public List<Operators> getOperatorsList() {
		return operatorsList;
	}

	public void setOperatorsList(List<Operators> operatorsList) {
		this.operatorsList = operatorsList;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public Operators getAgent() {
		return agent;
	}

	public void setAgent(Operators agent) {
		this.agent = agent;
	}

	public InputStream getExcelFile() {
		return excelFile;
	}

	public void setExcelFile(InputStream excelFile) {
		this.excelFile = excelFile;
	}

	public String getExcelName() {
		return excelName;
	}

	public void setExcelName(String excelName) {
		this.excelName = excelName;
	}

	/**
	 * 通过查询条件组装sql
	 * @param accountNo
	 * @param minDate
	 * @param maxDate
	 * @param orgCode
	 * @param isHTX 是否是和天下
	 * @return
	 */
	public  static String getSql(String accountNo,String minDate,String maxDate,String orgCode,boolean isHTX) {

		StringBuffer stb = new StringBuffer(
				" select (select real_name from t_operators where account_no='"
						+ accountNo + "') real_name,");
		stb
				.append(" MCC_TYPE_NAME,count(*) count1,round(sum(AMOUNT),2) AMOUNT,round(sum(fenrun_AMT),2) fenrun_AMT,round(sum(MERFEE),2) MERFEE from (");
		stb
				.append(" SELECT X.*,CASE WHEN COMM_MODE = '3' THEN (MERFEE- least(AMOUNT * PROFIT_FEE / 100,max_fee)) * PROFIT_SETTLE_RATE/100");
		stb
				.append(" ELSE (TO_NUMBER(MERFEE) - AMOUNT * PROFIT_FEE / 100) * PROFIT_SETTLE_RATE/100  END AS fenrun_AMT");
		stb
				.append(" FROM (SELECT V.*, TP.MAX_FEE, TP.PROFIT_FEE, TP.PROFIT_SETTLE_RATE,TP.MCC_TYPE_NAME");
		stb
				.append(" FROM (SELECT EM.AGENT_ID, E.MID, E.COMM_MODE,e.comm_rate,e.comm_amt,E.MCC,");
		// stb.append(" (SELECT o.account_no FROM t_operators o WHERE o.id = em.agent_id) account_no,");
		stb
				.append(" (SELECT O.ACCOUNT_NO FROM T_OPERATORS O WHERE O.account_no ='"
						+ accountNo + "') ACCOUNT_NO,");
		stb
				.append(" (SELECT TM.MCC_TYPE FROM T_MCC_CODE TM WHERE TM.MCC_CODE = E.MCC) MCC_TYPE,");
		stb
				.append(" TT.MERFEE,TT.AMOUNT  FROM T_TRANSJNLS_CALCU TT, ESMIDINFO E,ESMIDINFO_MERINFO EM");
		stb
				.append(" WHERE TT.MERNO = E.MID AND E.MID = EM.MERCHANT AND TT.SETT_FLAG = 'Y'");
		stb.append(" AND TT.ETSDATE >= '" + minDate + "'");
		stb.append(" AND TT.ETSDATE <= '" + maxDate + "'");
		
		if(isHTX){
		   stb.append(" AND TT.htxflag = '1' ");	
		}else{
		   stb.append(" AND TT.htxflag <> '1' ");
		}
		
		stb.append(" AND em.agent_id IN(");
		stb
				.append(" SELECT T.ID FROM T_OPERATORS T WHERE T.ROLE_TYPE <> '15' ");
		
		if(!"".equals(Constance.Null2EmptyTrim(orgCode))){
			stb.append(" and  T.ORG_CODE = '" + orgCode + "'");	
		}
		
		stb
				.append(" START WITH ID = (select id from t_operators where account_no='"
						+ accountNo + "') ");
		stb.append(" CONNECT BY PRIOR T.ID = T.SUPRI_ID )) V,");
		stb
				.append(" (SELECT * FROM t_profit_rule r WHERE r.agent_id=(SELECT s.account_no FROM t_operators s WHERE s.account_no ='"
						+ accountNo + "')) TP");
		stb
				.append("  WHERE V.MCC_TYPE = TP.MCC_TYPE_CODE AND V.COMM_MODE = TP.PARAM_NAME1 and v.account_no = tp.agent_id) X");
		stb.append(") group by MCC_TYPE_NAME");

		return stb.toString();
	}

}
